package mbms.mobilebudget.expense;

import java.sql.SQLException;

import mbms.mobilebudget.database.DatabaseHandler;
import mbms.mobilebudget.entity.BankAccount;
import mbms.mobilebudget.entity.CreditCard;
import mbms.mobilebudget.entity.Expense;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.j256.ormlite.dao.Dao;

@SuppressLint("ShowToast")
public class ExpenseManager {

	private DatabaseHandler helper;
	private Context context;
	private BankAccount passedBankAccount;
	private CreditCard passedCreditCard;

	public ExpenseManager(DatabaseHandler helper, Context context, BankAccount bankAccount,CreditCard creditCard) {
		this.helper = helper;
		this.context = context;
		this.passedBankAccount = bankAccount;
		this.passedCreditCard = creditCard;
	}
	
	public Expense addExpense(Expense exp){
		try {
			if(passedBankAccount!=null && passedCreditCard !=null){
				return null;
			}
			else if(passedBankAccount!=null){
				exp.setBankAccount(passedBankAccount);
				exp.setCreditCard(null);
				Dao<Expense,Integer> expenseDao = helper.getExpenseDao();
				expenseDao.create(exp);
				updateTotalAmountBankAccount(exp.getAmount());
				Log.d("Insertion",expenseDao.queryForId(exp.getId()).getId()+ " id inserted");
			}
			else if (passedCreditCard!=null){
				exp.setCreditCard(passedCreditCard);
				exp.setBankAccount(null);
				Dao<Expense,Integer> expenseDao = helper.getExpenseDao();
				expenseDao.create(exp);
				updateTotalAmountCreditCard(exp.getAmount());
				Log.d("Insertion",expenseDao.queryForId(exp.getId()).getId()+ " id inserted");
			}
			else{
				return null;
			}
			
			
		} catch (SQLException e) {
			e.printStackTrace();
			Log.e("error", "add expense");
			return null;
		}
		return exp;
	}
	
	public Expense updateExpense(Expense account){
		try {
			Dao<Expense,Integer> expenseDao = helper.getExpenseDao();
			Expense updatedExpense= expenseDao.queryForId(account.getId());
			if(updatedExpense==null || updatedExpense.getId()==null){
				Toast.makeText(context, "id not retrieved while updating",
						Toast.LENGTH_LONG);
				return null;
			}
			else{
				Double difference = account.getAmount()- updatedExpense.getAmount();
				copyExpense(account, updatedExpense);
				expenseDao.update(updatedExpense);
				if(passedBankAccount!=null){
					updateTotalAmountBankAccount(difference);
				}
				else if (passedCreditCard!=null){
					updateTotalAmountCreditCard(difference);
				}
					Toast.makeText(context, "update with id : " + updatedExpense.getId(),
							Toast.LENGTH_LONG);
				return updatedExpense;
			}
		} catch (SQLException e) {
			Log.e("error", "update expense");
			Log.e("error", e.getStackTrace().toString());
			return null;
		}
		
		
	}
	public Expense deleteExpense(Expense account){
		try {
			Dao<Expense,Integer> expenseDao = helper.getExpenseDao();
			Expense beDeleted= expenseDao.queryForId(account.getId());
			if(beDeleted==null || beDeleted.getId()==null){
				Toast.makeText(context, "id not retrieved while deleting", Toast.LENGTH_LONG);
				return null;
			}
			else{
				expenseDao.delete(beDeleted);
				if(passedBankAccount!=null){
					updateTotalAmountBankAccount(beDeleted.getAmount()*Double.valueOf(-1));
				}
				else if (passedCreditCard!=null){
					updateTotalAmountCreditCard(beDeleted.getAmount()*Double.valueOf(-1));
				}
				return beDeleted;
			}
		} catch (SQLException e) {
			Log.e("error", "delete expense");
			return null;
		}
		
	}
	
	private void copyExpense(Expense gives, Expense takes){
		takes.setAmount(gives.getAmount());
		takes.setCurrencyType(gives.getCurrencyType());
		takes.setDateOfExpense(gives.getDateOfExpense());
		takes.setExpenseCategory(gives.getExpenseCategory());
		takes.setExpenseExplanation(gives.getExpenseExplanation());
		
	}
	private void updateTotalAmountCreditCard(Double amount){
		try {
			Dao<CreditCard, Integer> dao = helper.getCreditCardDao();
			CreditCard updated= dao.queryForId(passedCreditCard.getId());
			if(updated==null || updated.getId()==null){
				Log.e("error", "id not retrieved while updating credit card amount") ;
				return;
			}
			else{
				if(updated.getTotalExpenseAmount() == null){
					updated.setTotalExpenseAmount(amount);
				}
				else{
					updated.setTotalExpenseAmount(updated.getTotalExpenseAmount()+amount);
				}
				dao.update(updated);
				
			}
		}catch (SQLException e) {
			Log.e("error", "id not retrieved while updating credit card amount") ;
		}
	}
	private void updateTotalAmountBankAccount(Double amount){
		try {
			Dao<BankAccount, Integer> dao = helper.getBankAccountDao();
			BankAccount updated= dao.queryForId(passedBankAccount.getId());
			if(updated==null || updated.getId()==null){
				Log.e("error", "id not retrieved while updating bank account amount") ;
				return;
			}
			else{
				if(updated.getTotalExpenseAmount() == null){
					updated.setTotalExpenseAmount(amount);
				}
				else{
					updated.setTotalExpenseAmount(updated.getTotalExpenseAmount()+amount);
				}
				dao.update(updated);
				
			}
		}catch (SQLException e) {
			Log.e("error", "id not retrieved while updating bank account amount") ;
		}
	}
}
